/*
 * Powered By XY
 * Since 2020
 */

package com.xy.biz.uc.service.impl;

import com.xy.biz.base.client.DictClient;
import com.xy.biz.base.domain.req.GetDictByCodeRequest;
import com.xy.biz.base.domain.resp.ListDictItemResponse;
import com.xy.biz.uc.domain.bo.TeamBO;
import com.xy.biz.uc.domain.bo.TeamUserRelBO;
import com.xy.biz.uc.domain.consts.TeamConstant;
import com.xy.biz.uc.domain.converter.TeamConverter;
import com.xy.biz.uc.domain.converter.TeamUserRelConverter;
import com.xy.biz.uc.domain.enums.TeamTypeEnum;
import com.xy.biz.uc.domain.query.TeamQuery;
import com.xy.biz.uc.domain.query.TeamUserRelQuery;
import com.xy.biz.uc.domain.req.*;
import com.xy.biz.uc.domain.resp.GetTeamResponse;
import com.xy.biz.uc.event.TeamEventBus;
import com.xy.biz.uc.manager.TeamManager;
import com.xy.biz.uc.service.TeamService;
import com.xy.lang.domain.Result;
import com.xy.tool.context.UserContextHolder;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.xy.biz.uc.domain.bo.TeamUserRelBO.JOIN_STATUS_JOINED;
import static com.xy.biz.uc.domain.bo.TeamUserRelBO.ROLE_ADMIN;

/**
 *
 *
 * @author yzh
 * @date 2021-4-26
 */
@Service
public class TeamServiceImpl implements TeamService {

    @Autowired
    private TeamManager teamManager;

    @Autowired
    private DictClient dictClient;

    @Autowired
    private TeamEventBus teamEventBus;

    @Override
    public Result<?> saveTeam(SaveTeamRequest request) {
        int count = teamManager.countTeam(TeamQuery.builder()
                .createUserId(UserContextHolder.getUserId()).build());
        Result<ListDictItemResponse> dictItem = dictClient.getDictItem(GetDictByCodeRequest.builder()
                .dictGroupCode(TeamConstant.TEAM_SETTING)
                .dictCode(TeamConstant.TEAM_UPPER_SIZE_PERSON).build());
        if (dictItem.wasSuccess()) {
            if (Integer.parseInt(dictItem.getData().getDictValue()) == count) {
                return Result.fail(Result.CONFLICT, "个人团队数量已达上线");
            }
        }
        TeamBO teamBO = TeamConverter.toBO(request);
        buildTeamBO(teamBO);
        int row = teamManager.saveTeam(teamBO);
        if (row > 0) {
            return Result.success();
        }

        return Result.ofErrorRowsAffected();
    }

    private void buildTeamBO(TeamBO teamBO) {
        Result<ListDictItemResponse> dictItem = dictClient.getDictItem(GetDictByCodeRequest.builder()
                .dictGroupCode(TeamConstant.TEAM_SETTING)
                .dictCode(TeamConstant.TEAM_MEMBER_SIZE_PERSON).build());
        if (dictItem.wasSuccess()) {
            teamBO.setCapacitySize(Integer.parseInt(dictItem.getData().getDictValue()));
        }
        LocalDateTime now = LocalDateTime.now();
        teamBO.setTenantId(UserContextHolder.getTenantId());
        teamBO.setMemberSize(1);
        teamBO.setType(TeamTypeEnum.CUSTOM.getCode());
        teamBO.setCreateUserId(UserContextHolder.getUserId());
        teamBO.setCreateTime(now);
        teamBO.setUpdateTime(now);

        TeamUserRelBO teamUserRelBO = new TeamUserRelBO();
        teamUserRelBO.setUserId(UserContextHolder.getUserId());
        teamUserRelBO.setRole(ROLE_ADMIN);
        teamUserRelBO.setJoinStatus(JOIN_STATUS_JOINED);
        teamUserRelBO.setJoinTime(now);
        teamUserRelBO.setCreateUserId(UserContextHolder.getUserId());
        teamUserRelBO.setCreateTime(now);
        teamBO.addMember(teamUserRelBO);
    }

    @Override
    public Result<?> updateTeam(SaveTeamRequest request) {
        TeamBO teamBO = TeamConverter.toBO(request);
        teamBO.setUpdateTime(LocalDateTime.now());
        int affectedRows = teamManager.updateTeam(teamBO);
        if (affectedRows > 0) {
            return Result.success();
        }
        return Result.ofErrorRowsAffected();
    }

    @Override
    public Result<?> deleteTeam(Long teamId) {
        //先删除团队和人员关系
        deletedTeamUserRole(DeleteTeamUserRelRequest.builder().teamId(teamId).build());
        int affectedRows = teamManager.deleteTeam(teamId);
        if (affectedRows > 0) {
            //删除相应知识库
            teamEventBus.fireDocumentEditHandler(teamId);
            return Result.success();
        }
        return Result.ofErrorRowsAffected();
    }

    @Override
    public TeamBO getTeam(Long teamId) {
        return teamManager.getTeam(teamId);
    }

    @Override
    public List<TeamBO> listTeamById(Collection<java.lang.Long> collection) {
        return teamManager.listTeamById(collection);
    }

    @Override
    public List<TeamBO> listTeam(TeamQuery query) {
        return teamManager.listTeam(query);
    }

    @Override
    public int countTeam(TeamQuery query) {
        return teamManager.countTeam(query);
    }

    @Override
    public List<GetTeamResponse> listJoinedTeam(ListTeamRequest request) {
        TeamUserRelQuery teamUserRelQuery = TeamUserRelQuery.builder().userId(UserContextHolder.getUserId()).joinStatus(JOIN_STATUS_JOINED).build();
        List<TeamUserRelBO> teamUserRelBOS = teamManager.listTeamUserRel(teamUserRelQuery);
        if (CollectionUtils.isEmpty(teamUserRelBOS)) {
            return Collections.emptyList();
        }

        //加入条件查询 身份为管理源的团队
        if (!Objects.isNull(request.getRole())) {
            teamUserRelBOS = teamUserRelBOS.stream().filter(e -> e.getRole() == 1).collect(Collectors.toList());
        }
        Set<Long> teamIdSet = teamUserRelBOS.stream().map(e -> e.getTeamId()).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(teamIdSet)) {
            return null;
        }
        Map<Long, TeamUserRelBO> teamUserRelBOMap = teamUserRelBOS.stream().collect(Collectors.toMap(TeamUserRelBO::getTeamId, TeamUserRelBO -> TeamUserRelBO));

        List<TeamBO> teamBOList = teamManager.listTeamById(teamIdSet);
        List<GetTeamResponse> getTeamResponses = TeamConverter.toResponse(teamBOList);
        //团队名称筛选
        if (request.getTeamName() != null && request.getTeamName().trim() != "") {
            getTeamResponses.removeIf(e -> !e.getTeamName().contains(request.getTeamName()));
        }
        getTeamResponses.stream().forEach(item -> {
            TeamUserRelBO teamUserRelBO = teamUserRelBOMap.get(item.getTeamId());
            item.setRole(teamUserRelBO.getRole());
            item.setJoinTime(teamUserRelBO.getJoinTime());
        });
        return getTeamResponses;
    }


    @Transactional
    @Override
    public Result<?> inviteJoin(SaveTeamUserRelRequest request) {
        int row = teamManager.inviteJoin(request);
        if (row == -1) {
            return Result.fail(Result.CONFLICT, "添加人数超过团队上限");
        }
        if (row > 0) {
            //加入人员后将重新设置团队成员
            return Result.success();
        }
        return Result.fail(Result.CONFLICT, "没有可添加成员");
    }

    @Override
    public Result<?> updateTeamUserRole(UpdateTeamUserRelRequest request) {
        int row = teamManager.updateTeamUserRel(TeamUserRelConverter.toBO(request));
        if (row > 0) {
            return Result.success();
        }
        return Result.ofErrorRowsAffected();
    }

    @Transactional
    @Override
    public Result<?> deletedTeamUserRole(DeleteTeamUserRelRequest request) {
        int row = teamManager.deleteTeamUserRel(request);
        if (row > 0) {
            return Result.success();
        }
        return Result.ofErrorRowsAffected();
    }

    @Override
    public List<TeamUserRelBO> listTeamUser(ListTeamUserRelRequest request) {
        TeamUserRelQuery teamUserRelQuery = TeamUserRelConverter.toQuery(request);
        teamUserRelQuery.setJoinStatus(JOIN_STATUS_JOINED);
        List<TeamUserRelBO> teamUserRelBOS = teamManager.listTeamUserRel(teamUserRelQuery);
        return teamUserRelBOS;
    }

    @Override
    public Result<Boolean> isTeamAdmin(Long teamId) {
        List<TeamUserRelBO> teamUserRelBOList = teamManager.listTeamUserRel(TeamUserRelQuery.builder()
                .teamId(teamId)
                .userId(UserContextHolder.getUserId())
                .build());
        if (CollectionUtils.isEmpty(teamUserRelBOList)) {
            return Result.ofNotFound("未找到团队", teamId);
        }
        TeamUserRelBO teamUserRelBO = teamUserRelBOList.get(0);
        return Result.success(Objects.equals(ROLE_ADMIN, teamUserRelBO.getRole()));
    }

    /**
     * 当前用户是否是团队管理员
     *
     * @param teamIds
     * @return
     */
    @Override
    public Result<Set<Long>> isTeamAdminS(Collection<Long> teamIds) {
        List<TeamUserRelBO> teamUserRelBOList = teamManager.listTeamUserRel(TeamUserRelQuery.builder()
                .teamIds(teamIds)
                .userId(UserContextHolder.getUserId())
                .build());
        if (CollectionUtils.isEmpty(teamUserRelBOList)) {
            return Result.ofNotFound("未找到团队", teamIds);
        }
        Set<Long> teamId = teamUserRelBOList.stream().filter(t -> Objects.equals(ROLE_ADMIN, t.getRole())).map(TeamUserRelBO::getTeamId).collect(Collectors.toSet());
        return Result.success(teamId);
    }
}
